package com.lk.netty;

import com.lk.netty.encode.UserMessageDecode;
import com.lk.netty.encode.UserMessageEncode;
import com.lk.netty.message.BaseMessage;
import com.lk.netty.message.UserMessage;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class EchoClient {

    private final String host;
    private final int port;
    private BaseMessage message;

    public EchoClient(String host, int port) {
        this.host = host;
        this.port = port;

    }

    public void run() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new StringDecoder());
                            pipeline.addLast(new StringEncoder());
                            pipeline.addLast(new UserMessageDecode());
                            pipeline.addLast(new UserMessageEncode());
                            pipeline.addLast(new EchoClientHandler());
                        }
                    });

            // 连接到服务器
            ChannelFuture future = b.connect(host, port).sync();
//            ChannelFuture future = b.connect("localhost", 8080).sync();
//            String msg = "hello Server!";
//            ByteBuf encoded = future.channel().alloc().buffer(4 * msg.length());
//            encoded.writeBytes(msg.getBytes());
//            future.channel().writeAndFlush(encoded);

            future.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) {
                    if (future.isSuccess()) {

                        // 连接成功，可以写数据到通道
                        String msg = "hello Server !";
                        ByteBuf encoded = future.channel().alloc().buffer(4 * msg.length());
                        encoded.writeBytes(msg.getBytes());


                        String message = "Hello, Netty!";
//                        future.channel().writeAndFlush(message);
                        UserMessage message1 = new UserMessage();
                        message1.setUsername("aaaa");
                        future.channel().writeAndFlush(message);
                        future.channel().writeAndFlush("hello, jassic");
                        future.channel().writeAndFlush(message1);
                    } else {
                        // 连接失败，处理异常
                        Throwable cause = future.cause();
                        cause.printStackTrace();
                    }
                }
            });
            future.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        String host = "localhost";
        int port = 8080;
        UserMessage message = new UserMessage();
        message.setUsername("aaaa");

        new EchoClient(host, port).run();
    }


    // 自定义的 ChannelHandler 处理器
    private static class EchoClientHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelActive(ChannelHandlerContext ctx) {


//            String msg = "hello Server!";
//            ByteBuf encoded = ctx.alloc().buffer(4 * msg.length());
//            encoded.writeBytes(msg.getBytes());
//            ctx.write(encoded);
//            ctx.flush();
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            System.out.println("client :channelRead"); // 接收服务器的消息并打印
            ByteBuf buffer = (ByteBuf) msg;
            byte[] bytes = new byte[buffer.readableBytes()];
            buffer.readBytes(bytes);
            buffer.release();

            System.out.println("Received from server: " + new String(bytes)); // 接收服务器的消息并打印
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            System.out.println("aaaaa");
            cause.printStackTrace();
            ctx.close(); // 发生异常时关闭连接
        }
    }
}